package dbExec

import (
	"database/sql"
	"reflect"
	"sync"
	"time"
)

var mu sync.Mutex

type (
	TableMetadata struct {
		Schema              string `json:"schema"`
		Table               string `json:"table"`
		MapTable            map[string]string
		IgnoreTable         string
		Drive               string
		DBType              string
		DB                  *sql.DB `json:"db"`
		Datafix             string
		LowerCaseTableNames bool  `json:"lowerCaseTableNames"`
		LogThreadSeq        int64 `json:"logThreadSeq"`
		DBname              string
		EndTime             time.Duration `json:"endTime"`
	}
)

type TableStructMetadataer interface {
	TableColumnName1(db *sql.DB, schema, table string, logThreadSeq int64) ([]map[string]interface{}, error)
	TableColumnTypeConvert(v []string, logThreadSeq int64) []string
	//GlobalAccessPri(db *sql.DB) (bool, error)
	//TableAccessPriCheck(db *sql.DB, checkTableList []string, datefix string) (map[string]int, error)
	//DatabaseNameList(db *sql.DB, checkSchema map[string]int) (map[string]int, error)
	//	TableAllColumn(db *sql.DB, tableName map[string]int) (map[string][]global.TableMeta, error)
	//TableDistribution(db *sql.DB, schema string, table []string) ([]map[string]interface{}, error)
	//TableIndexChoice(queryData []global.IndexColumn, logThreadSeq int64) global.IndexSelection
	//TableIndexColumn(db *sql.DB, schema string, table []string) ([]global.IndexColumn, error)
	//TableIndexMerge(queryData []global.IndexColumn, logThreadSeq int64) global.IndexMerge
	//GetTablePartitionConfiguration(db *sql.DB, schema, table string) (tpc []global.TablePartitionConfig, err error)
	Trigger(db *sql.DB, logThreadSeq int64) (map[string]string, error)
	Proc(db *sql.DB, logThreadSeq int64) (map[string]string, error)
	Func(db *sql.DB, logThreadSeq int64) (map[string]string, error)
	Struct(db *sql.DB) (map[string]string, error)
	Foreign(db *sql.DB, logThreadSeq int64) (map[string]string, error)
}

func tableMetadataInit(ff *TableMetadata) (t TableStructMetadataer) {
	mu.Lock()
	defer func() {
		mu.Unlock()
	}()
	if v1, ok := dbTypeInterFuncRef[ff.DBname]; ok {
		if v1.Kind() == reflect.Func {
			args := []reflect.Value{
				reflect.ValueOf(ff),
				reflect.ValueOf(metaDataAPI[ff.DBname]),
			}
			i := v1.Call(args)
			for ii := 0; ii < len(i); ii++ {
				t = i[ii].Interface().(TableStructMetadataer)
			}
		}
	}
	return
}
func Instance(config *TableMetadata) TableStructMetadataer {
	return tableMetadataInit(config)
}
